package com.zyl.nettyhttp;

import lombok.extern.slf4j.Slf4j;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

@Slf4j
public final class HttpHelloWorldServer {

    static final int PORT = 8888;

    public static void main(String[] args) throws Exception {
        // Configure the server.
        //创建一个 bossGroup，负责接收客户端连接
        //只包含一个线程，因为它仅负责接收连接，不处理具体业务
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        //创建一个 workerGroup，负责处理连接后的I/O操作。
        //包含多个线程，具体数量默认为CPU核心数乘以2。
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //创建一个 ServerBootstrap 实例，用于配置服务器
            ServerBootstrap b = new ServerBootstrap();
            //设置 SO_BACKLOG 选项，指定了内核为此套接口排队的最大连接个数
            b.option(ChannelOption.SO_BACKLOG, 1024);
            //设置 TCP_NODELAY 选项，禁用Nagle算法，提高传输即时性
            b.childOption(ChannelOption.TCP_NODELAY,true);
            //设置 SO_KEEPALIVE 选项，启用TCP保持连接检测，确保连接的长期闲置状态下的有效性
            b.childOption(ChannelOption.SO_KEEPALIVE,true);
            //配置 bossGroup 和 workerGroup
            b.group(bossGroup, workerGroup)
                    //指定服务器通道类型为 NioServerSocketChannel，用于非阻塞I/O操作
                    .channel(NioServerSocketChannel.class)
                    //为 bossGroup 配置一个日志处理器，用于记录服务器的各类事件，日志级别为 INFO
                    .handler(new LoggingHandler(LogLevel.INFO))
                    //为 workerGroup 配置一个自定义的初始化器 HttpHelloWorldServerInitializer，用于初始化通道的处理器
                    .childHandler(new HttpHelloWorldServerInitializer());
            //绑定端口 PORT 并启动服务器，同步等待绑定完成。
            //获取绑定端口后的通道实例 ch
            Channel ch = b.bind(PORT).sync().channel();
            log.info("Netty http server listening on port "+ PORT);
            //阻塞等待服务器通道关闭
            ch.closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
